<template>
    <div>
        <!-- <h1>当前求和为：{{$store.state.sum}} </h1>
        <h1>当前求和放大十倍为：{{$store.getters.bigSum}} </h1> -->
        <h1>当前求和为：{{sum}} </h1>
        <h1>当前求和放大十倍为：{{bigSum}} </h1>

        <!-- <h1 style="color: brown;">Persons组件的总人数：{{personList.length}}</h1> -->

        <!-- 由于此处写了大量重复的$store.state.xxx代码，此处需要进行简写的话，可以使用计算属性 -->
        <!-- <h1>我在：{{$store.state.school}} 学习：{{$store.state.subject}}</h1> -->
        <h1>我在：{{school}} 学习：{{subject}}</h1>
        <select v-model.number="num">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>

        <!-- 如果mapMutations使用对象写法的话，就可以使用小写，才找到方法，再去找对应的mapMutations才可以 -->
        <button @click="increment(num)">+</button>
        <button @click="decrement(num)">-</button>
        <!-- 如果mapMutations使用的数组写法的话，就需要使用大写，直接指定mapMutations才可以 -->
        <!-- <button @click="INCREMENT(num)">+</button>
        <button @click="DECREMENT(num)">-</button> -->

        <!-- 如果mapActions使用对象写法的话，就可以使用小写，才找到方法，再去找对应的mapActions才可以 -->
        <!-- <button @click="incrementOdd(num)">当前求和为奇数再加</button>
        <button @click="incrementWait(num)">等一等再加</button> -->
        <!-- 如果mapActions使用的数组写法的话，就需要使用大写，直接指定mapActions才可以 -->
        <button @click="incrementOdd(num)">当前求和为奇数再加</button>
        <button @click="incrementWait(num)">等一等再加</button>

        <hr>
    </div>
</template>

<script>
    // 如果想要使用mapState的话，需要提前导入
    import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';

    export default {
        name: 'Count',
        data() {
            return {
                num: 1,// 用户选择的数字
                // sum: 0,// 当前的和，将该sum放到store的state里面。
            }
        },
        mounted() {
            console.log('@我想要查看Count组件里面是否有store：', this)
        },
        computed: {
            // 靠程序员自己亲自去写计算属性。
            // 但是使用计算属性也写了很多重复的代码this.$store.state.xxx、this.$store.getters.xxx，也很麻烦

            // 这样整体是一个函数，其中属性名叫做sum，属性值是一个function函数，这样可以称之为一个方法
            // 其中function后面的he就是一个方法的名称，而he这个方法的名称没有意义，一般直接省略。
            // sum:function he() {
            //     return this.$store.state.sum;
            // },

            // sum() {
            //     return this.$store.state.sum;
            // },
            // school() {
            //     return this.$store.state.school;
            // },
            // subject() {
            //     return this.$store.state.subject;
            // },

            // 使用es6语法的展开运算符，然后结合Vue提供的mapState方法可以缩写。
            // 重点一：借助mapState生成计算属性，从state中读取数据。（对象写法）
            // ...mapState({
            //     // 'sum': 'sum',
            //     // 'school': 'school',
            //     // 'subject': 'subject',

            //     // 下面的属性名可以省略单引号的写法，到时候会自动帮助携带上的。
            //     sum: 'sum',
            //     school: 'school',
            //     subject: 'subject'
            // }),

            // 重点二：借助mapState生成计算属性，从state中读取数据。（数组写法）
            // 数组写法，索引值是两种用途，第一种是生成的计算属性名称xxxx，第二种是获取到的对象的属性名this.$store.state.xxxx
            // ...mapState([
            //     'sum',
            //     'school',
            //     'subject',
            //     'personList',
            // ]),

            // 如果是模板化的话，就需要使用模块化的名称才可以，而不能直接进行使用
            // 此时就需要使用countOptions.xxxx、personsOptions.xxxx来获取到变量的值。
            // ...mapState([
            //     'countOptions',
            //     'personsOptions'
            // ]),

            // 如果想要直接使用state里面的变量的话，可以使用命名空间的语法来书写
            // ...mapState(
            //     'countOptions',
            //     [
            //         'sum',
            //         'school',
            //         'subject',
            //     ]
            // ),
            ...mapState('countOptions', ['sum', 'school', 'subject']),
            // ...mapState(
            //     'personsOptions',
            //     [
            //         'personList',
            //     ]
            // ),
            ...mapState('personsOptions', ['personList']),

            // ********************************************************
            // bigSum() {
            //     return this.$store.getters.bigSum;
            // },

            // 重点一：借助mapGetters生成计算属性，从getters中读取数据。（对象写法）
            // ...mapGetters({
            //     bigSum: 'bigSum'
            // }),

            // 重点二：借助mapGetters生成计算属性，从getters中读取数据。（数组写法）
            // ...mapGetters([
            //     'bigSum'
            // ]),

            // 如果想要书写模块化的话，就要这样
            ...mapGetters('countOptions', [
                'bigSum'
            ]),
        },
        methods: {
            // // 程序员亲自写方法
            // increment() {
            //     // this.sum += this.num;
            //     // 组件调用store身上的dispatch方法
            //     // this.$store.dispatch('increment', this.num);

            //     // 如果Vuex的Action里面没有业务逻辑的话，可以跳过Action步骤，直接进入到Mutations步骤
            //     this.$store.commit('INCREMENT', this.num);
            // },
            // decrement() {
            //     // this.sum -= this.num;
            //     // 组件调用store身上的dispatch方法
            //     // this.$store.dispatch('decrement', this.num);

            //     // 如果Vuex的Action里面没有业务逻辑的话，可以跳过Action步骤，直接进入到Mutations步骤
            //     this.$store.commit('DECREMENT', this.num);
            // },

            // 重点一：借助mapMutations生成对应的方法，方法中会调用commit去联系mutations(对象写法)
            ...mapMutations('countOptions', {
                increment: 'INCREMENT',
                decrement: 'DECREMENT'
            }),

            // 重点二：借助mapMutations生成对应的方法，方法中会调用commit去联系mutations(数组写法)
            // ...mapMutations([
            //     'INCREMENT',
            //     'DECREMENT'
            // ]),

            // // *************************************************
            // incrementOdd() {
            //     // // 如果当前求和sum 取余2 为零的话，说明是偶数就不能执行该逻辑
            //     // // 其中0转换成布尔值就是false，可以省略写法
            //     // if (this.num % 2) {
            //     //     this.sum += this.num;
            //     // }

            //     // 组件调用store身上的dispatch方法
            //     this.$store.dispatch('incrementOdd', this.num);
            // },
            // incrementWait() {
            //     setTimeout(() => {
            //         // this.sum += this.num;

            //         // 组件调用store身上的dispatch方法
            //         this.$store.dispatch('incrementWait', this.num);
            //     }, 500);
            // }

            // 重点一：借助mapActions生成对应的方法，方法中会调用dispatch去联系actions(对象写法)
            // ...mapActions({
            //     incrementOdd: 'incrementOdd',
            //     incrementWait: 'incrementWait'
            // }),
            // 重点二：借助mapActions生成对应的方法，方法中会调用dispatch去联系actions(数组写法)
            ...mapActions('countOptions', [
                'incrementOdd',
                'incrementWait'
            ]),
        },
        mounted() {
            // 可以打印输出mapState的输出结果
            const x = mapState({ he: 'sum', xuexiao: 'school', xueke: 'subject' })
            console.log(x)
        },
    }
</script>

<style scoped>
    button {
        margin-left: 5px;
    }
</style>